[Arduino]关于arduino中volatile关键字的使用

您所在的位置:网站首页 arduino pinmode什么意思 [Arduino]关于arduino中volatile关键字的使用

[Arduino]关于arduino中volatile关键字的使用

2024-05-30 06:52| 来源: 网络整理| 查看: 265

Volatile:

Volatile是一个被称为变量限定符的关键字,它通常被用在变量的数据类型之前,用来修改编译器和后续程序处理变量的方式。 声明volatile变量是对编译器的指令。编译器是把你的C/ c++代码翻译成机器码的软件,机器码是Arduino中Atmega芯片的真正指令。 具体来说,它指示编译器从RAM而不是从存储寄存器加载变量,存储寄存器是存储和操作程序变量的临时内存位置。在某些条件下,存储在寄存器中的变量的值可能是不准确的。 当变量的值可能被超出其所在代码段的控制范围的东西(例如并发执行的线程)改变时,就应该将其声明为volatile。在Arduino中,唯一可能发生这种情况的地方是与中断相关的代码部分,称为中断服务例程。

int or long volatiles: 如果volatile变量大于一个字节(例如16位int或32位long),那么微控制器(MCU根据自己的Arduino具体型号确定,这里使用Arduino Mega 2560,它是8位的MCU)不能一步读取它,因为它是8位微控制器。这意味着当你的主代码部分(例如循环)读取变量的前8位时,中断可能已经改变了后8位。这将为变量产生随机值。 解决方案: 当变量被读取时,中断需要被禁用,这样它们就不会在被读取时打乱位。有几种方法可以做到这一点:

LANGUAGE noInterrupts use the ATOMIC_BLOCK macro.

原子操作是单MCU操作-最小的可能单元

Example Code: volatile修饰符确保对状态变量的更改在loop()中立即可见。如果没有volatile修饰符,状态变量可以在进入函数时加载到寄存器中,并且在函数结束之前不会再更新。

// Flashes the LED for 1 s if the input has changed // in the previous second. volatile byte changed = 0; void setup() { pinMode(LED_BUILTIN, OUTPUT); attachInterrupt(digitalPinToInterrupt(2), toggle, CHANGE); } void loop() { if (changed == 1) { // toggle() has been called from interrupts! // Reset changed to 0 changed = 0; // Blink LED for 200 ms digitalWrite(LED_BUILTIN, HIGH); delay(200); digitalWrite(LED_BUILTIN, LOW); } } void toggle() { changed = 1; }

要访问一个比微控制器的8位数据总线大的变量,使用ATOMIC_BLOCK宏。宏确保在原子操作中读取变量,也就是说,在读取变量时,不能修改变量的内容。

#include // this library includes the ATOMIC_BLOCK macro. volatile int input_from_interrupt; // Somewhere in the code, e.g. inside loop() ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // code with interrupts blocked (consecutive atomic operations will not get interrupted) int result = input_from_interrupt; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3